/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.logical.allhit;

import com.logical.allhit.gui.MainView;
import com.logical.allhit.http.HTTPClient;
import com.logical.allhit.setting.Setting;
import com.logical.allhit.store.StorageManager;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Toolkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.net.URL;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.UIManager;
import javax.swing.WindowConstants;

/**
 * Kernel class is essential part of this application. kernel init all app
 * component end also launch main view of app.
 *
 * @author Sanjeet Jha
 */
public class Kernel {

    private JFrame frame;
    private JLabel progressLabel;
    private JProgressBar progressBar;

    private Kernel() {
        super();
    }
    /**
     * static Instance of Kernel class
     */
    private static final Kernel instance = new Kernel();

    /**
     * to get an instance of Kernel
     *
     * @return get an instance of Kernel
     * @throws Exception
     */
    public static Kernel getInstance() throws Exception {
        return instance;
    }

    /**
     * method for Launch application
     *
     * @param args
     * @throws Exception
     */
    public void launch(String[] args) throws Exception {
        ResourceBundle bundle =
                ResourceBundle.getBundle("com/logical/allhit/resouer/app");
        frame = new JFrame(bundle.getString("app.name"));
        frame.getAccessibleContext().setAccessibleDescription(
                bundle.getString("app.accessibleDescription"));
        int WIDTH = 400, HEIGHT = 300;
        frame.setSize(WIDTH, HEIGHT);
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        frame.setLocation(d.width / 2 - WIDTH / 2, d.height / 2 - HEIGHT / 2);
        frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        JOptionPane.setRootFrame(frame);
        JPanel progressPanel = new JPanel() {
            @Override
            public Insets getInsets() {
                return new Insets(40, 30, 20, 30);
            }
        };
        progressPanel.setLayout(new BoxLayout(progressPanel, BoxLayout.Y_AXIS));
        frame.getContentPane().add(progressPanel, BorderLayout.CENTER);
        URL imgUrl = null;
        ImageIcon imgIcon = null;
        imgUrl = Kernel.class.getResource("resouer/logo.png");
        imgIcon = new ImageIcon(imgUrl);
        Image img = imgIcon.getImage();
        frame.setIconImage(img);
        Dimension labelSize = new Dimension(400, 40);
        JLabel nameLabel = new JLabel(bundle.getString("app.name") + " " + bundle.getString("app.version"));
        nameLabel.setFont(new java.awt.Font("Monotype Corsiva", 0, 36));
        nameLabel.setMaximumSize(labelSize);
        nameLabel.setPreferredSize(labelSize);
        nameLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        progressPanel.add(nameLabel);
        progressPanel.add(Box.createRigidArea(new Dimension(1, 20)));

        progressLabel = new JLabel("Loading, please wait...");
        progressLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        progressLabel.setMaximumSize(labelSize);
        progressLabel.setPreferredSize(labelSize);
        progressPanel.add(progressLabel);
        progressPanel.add(Box.createRigidArea(new Dimension(1, 20)));

        progressBar = new JProgressBar();
        progressBar.setStringPainted(true);
        progressLabel.setLabelFor(progressBar);
        progressBar.setAlignmentX(Component.CENTER_ALIGNMENT);
        progressBar.setMinimum(0);
        progressBar.setValue(0);
        progressBar.setMaximum(5);
        progressBar.getAccessibleContext().setAccessibleName(bundle.getString("app.accessiblename"));
        progressPanel.add(progressBar);
        frame.setVisible(true);
        progressLabel.setText("Logger Intializtion...");
        boolean debugOn = false;
        for (int i = 0; i < args.length; i++) {
            String url = args[i];
            if (url.equals("-debug")) {
                debugOn = true;
            }
        }
        initLogging(debugOn);
        progressBar.setValue(progressBar.getValue() + 1);
        progressLabel.setText("HTTP session Intialization....");
//        HTTPClient.getInstance().setSession();
        progressBar.setValue(progressBar.getValue() + 1);
        progressLabel.setText("Load setting....");
        Setting.getInstance().fireSettingChandeEvent();
        progressBar.setValue(progressBar.getValue() + 1);
        progressLabel.setText("Load Look and Feel....");
        initThemeConfig();
        progressBar.setValue(progressBar.getValue() + 1);
        progressLabel.setText("Open Main Window");
        MainView mainView = MainView.getInstance();
        Thread mainWidow = new Thread(mainView, "mainView");
        frame.setVisible(false);
        mainWidow.start();
        mainWidow.join();
        frame.setVisible(true);
    }

    /**
     * method for shutdown application
     */
    public void shutdown() {
        try {
            Setting.getInstance().save();
            HTTPClient.getInstance().shutdown();
            Logger.getLogger(Kernel.class.getName()).log(Level.INFO, "Shutdown application");
        } catch (Exception e) {
            Logger.getLogger(Kernel.class.getName()).log(Level.WARNING, e.getMessage(), e);
        }
    }

    private static void initThemeConfig() {
        Properties property = new Properties();
        try {
            property.load(new FileInputStream(new File(StorageManager.getInstance().getSettingsDirectory(), "lookandfeel.properties")));
        } catch (FileNotFoundException ex) {
            property.setProperty("app.lookandfeel", "Nimbus");
            try {
                FileOutputStream fos = new FileOutputStream(new File(StorageManager.getInstance().getSettingsDirectory(), "lookandfeel.properties"), false);
                property.store(fos, "Look And Feel Setting");
            } catch (Exception e) {
                Logger.getLogger(com.logical.allhit.setting.Setting.class.getName()).log(Level.WARNING, e.getMessage(),e);
            }
            Logger.getLogger(com.logical.allhit.setting.Setting.class.getName()).log(Level.WARNING, ex.getMessage(),ex);
        } catch(Exception e){
            Logger.getLogger(com.logical.allhit.setting.Setting.class.getName()).log(Level.WARNING, e.getMessage(),e);
        }
        String ThemeName = property.getProperty("app.lookandfeel");
//        try {
//            if (Runtime.getRuntime().maxMemory() < 400000000L) {
//                System.exit(0);
//            }
//        } catch (Exception e) {
//        }

//        try {
//
//            java.sql.ResultSet rsTheme = userinfo.con.prepareStatement("Select * from displaysettings where User_Id = " + userinfo.ID).executeQuery();
//            if (rsTheme.next()) { 
//                ThemeName = rsTheme.getString("ThemeName");
//            }
//            rsTheme.close();
//            rsTheme = null;
//        } catch (Exception ex) {
//        }

        UIManager.put("swing.boldMetal", Boolean.FALSE);
        JDialog.setDefaultLookAndFeelDecorated(true);
        JFrame.setDefaultLookAndFeelDecorated(true);
        Toolkit.getDefaultToolkit().setDynamicLayout(true);
        System.setProperty("sun.awt.noerasebackground", "true");

        try {
            javax.swing.UIManager.LookAndFeelInfo[] lfinfo = javax.swing.UIManager.getInstalledLookAndFeels();
            for (int i = 0; i < lfinfo.length; ++i) {
                if (lfinfo[i].getName().equalsIgnoreCase(ThemeName)) {
                    javax.swing.UIManager.setLookAndFeel(lfinfo[i].getClassName());
                    break;
                }
            }
        } catch (Exception ex) {
        }
    }

    /**
     * Intalizes logging for application by logging configuration file
     *
     * @param debugOn
     * @throws Exception
     */
    private void initLogging(boolean debugOn) throws Exception {
        // Set up debugging & console
        String loggingToken = debugOn ? "logging-debug" : "logging";
        java.io.InputStream in = this.getClass().getResourceAsStream("/resouer/" + loggingToken + ".properties");
        if (in == null) {
            in = this.getClass().getResourceAsStream("resouer/" + loggingToken + ".properties");
            if (in == null) {
                throw new java.io.IOException("Unable to locate logging properties file.");
            }
        }
        try {
            java.util.logging.LogManager.getLogManager().readConfiguration(in);
        } finally {
            in.close();
        }
        // Configure log4j
        Logger logger = Logger.getLogger(Kernel.class.getName());
        if (logger.isLoggable(Level.INFO)) {
            logger.warning("Entry(): Logger INFO level is enabled.");
            java.util.Properties properties = System.getProperties();
            java.util.Iterator i = properties.entrySet().iterator();
            while (i.hasNext()) {
                Map.Entry entry = (Map.Entry) i.next();
                logger.info("main(): " + entry.getKey() + "=" + entry.getValue());
            }
        }
    }

    public JFrame getFrame() {
        return frame;
    }
}
